import os
from datetime import datetime as dt, timedelta
from dateutil.relativedelta import relativedelta
import datetime
import pandas as pd
from handle import Handle, ProjectConfig
# from handle import ProjectBugsLevel_Enumeration

# 获取周数据
def get_weekNum(date):
    date = str(date).replace("-", "")
    date = date[:8]
    year = date[:4]
    month = date[4:6]
    day = date[-2:]
    end = int(dt(int(year), int(month), int(day)).strftime("%W"))
    begin = int(dt(int(year), 1, 1).strftime("%W"))
    weekNum = end - begin + 1
    return f"{year}_W{str(weekNum)}"

# 统计缺陷方法(周维度)
def statisticsData2Week(projectId):
    bugSnapshot_Path = Handle.bugSnapshotData_path
    bug_Path = Handle.bugData_path
    bugSnapshot_filePath = os.path.join(bugSnapshot_Path, f"{projectId}.pkl")
    bug_filePath = os.path.join(bug_Path, f"{projectId}.pkl")
    statisticsdata_path = Handle.statistics2Week_path
    statisticsFile = os.path.join(statisticsdata_path, f"{projectId}.pkl")
    
    bugs_snapshot:pd.DataFrame = pd.read_pickle(bugSnapshot_filePath)
    bug_basedata:pd.DataFrame = pd.read_pickle(bug_filePath)
    
    bugs_snapshot.drop_duplicates(subset=['projectId', 'bugId'], keep='last', inplace=True)
    bugs_snapshot.rename(columns={'bugId':'taskId'}, inplace=True)
    bugs = bug_basedata.copy()
    bugs_snapshot['tfsCloseTime'] = bugs_snapshot['tfsCloseTime'].apply(lambda x:dt.strptime(x, '%Y-%m-%d %H:%M:%S'))
    bugs_snapshot['tfsCreateTime'] = bugs_snapshot['tfsCreateTime'].apply(lambda x:dt.strptime(x, '%Y-%m-%d %H:%M:%S'))
    
    bugs_ext = bugs.copy()
    bugs_ext['bugsCreateYearMonth'] = bugs_ext['CreateTime'].apply(lambda x:str(x)[:-2])
    bugsCreateYearsMonth = list(set(bugs_ext['bugsCreateYearMonth'].to_list()))
    del bugs_ext
    bugsCreateYearsMonth.sort()
    
    startMonth = bugsCreateYearsMonth[0]
    start_date = dt.strptime(startMonth, "%Y%m")
    current_date = dt.now()
    current_date = current_date + relativedelta(months=1)
    bugsCreateYearsMonth = []
    while start_date <= current_date:
        year_month = start_date.strftime("%Y%m")
        start_date += relativedelta(months=1)
        bugsCreateYearsMonth.append(str(year_month))
    
    # 根据bug创建年份，生成年-周维度DF
    weekMapList = list()
    # 获取当前时间本周最后一天日期
    now = datetime.datetime.now()
    this_week_end = str(now + timedelta(days=6 - now.weekday()))[:10]
    
    for yearMonth in bugsCreateYearsMonth:
        year = yearMonth[:-2]
        month = yearMonth[-2:]
        start_day = f'{year}-{month}-01'
        end_month = int(month) + 1
        end_year = year
        if end_month > 12:
            end_month = 1
            end_year = str(int(year) + 1)
        end_month = str(end_month).zfill(2)
        end_day = f'{end_year}-{end_month}-01'
        if bugsCreateYearsMonth[-1] == yearMonth:
            end_day = this_week_end
        start_week = get_weekNum(start_day)
        
        date_rng = pd.date_range(start=start_day, end=end_day, freq='D')
        mondays = [int(str(i)[:10].replace('-','')) for i in date_rng[date_rng.weekday == 6]]
        for monday in mondays:
            weekMap = {}
            weekMap['week'] = start_week
            weekMap['weekDate'] = monday
            weekMapList.append(weekMap)
    df_template = pd.DataFrame(weekMapList)
    df_template['weekDate_ext'] = df_template['weekDate'].apply(lambda x:str(x))
    df_template['week_date_tmp'] = df_template['weekDate_ext'].apply(lambda x:f"{x[:4]}-{x[4:6]}-{x[-2:]}")
    df_template['week_date'] = df_template['week_date_tmp'].apply(Handle.str2datetime)
    df_template.drop(labels='weekDate_ext', axis=1, inplace=True)
    df_template.drop(labels='week_date_tmp', axis=1, inplace=True)
    df_template['week'] = df_template['weekDate'].apply(get_weekNum)
    
    # 获取项目下的缺陷分类枚举
    bugTypes = list(set(bug_basedata['bugType_name']))
    df_template_tmpL = []
    for i in bugTypes:
        for row in df_template.itertuples():
            row_dict = {
                "week" : getattr(row, "week"),
                "weekDate" : getattr(row, "weekDate"),
                "week_date" : getattr(row, "week_date"),
                "bugType_name" : i
            }
            df_template_tmpL.append(row_dict)
            
    df_template = pd.DataFrame(df_template_tmpL)
    df_template['bugType_name'] = df_template['bugType_name'].apply(lambda x:"无" if len(x) == 0 else x)
    
    base_data = pd.merge(bugs, bugs_snapshot, how='inner', on='taskId', suffixes=("_bugs", "_bugsSnapshot"))
    base_data['CreateWeek'] = base_data['tfsCreateTime'].apply(get_weekNum)
    base_data['CloseWeek'] = base_data['tfsCloseTime'].apply(get_weekNum)
    base_data['CreateDay'] = base_data['tfsCreateTime'].apply(lambda x:int(str(x)[:10].replace('-','')))
    base_data['CloseDay'] = base_data['tfsCloseTime'].apply(lambda x:int(str(x)[:10].replace('-','')))
    base_data['bugType_name'] = base_data['bugType_name'].apply(lambda x:"无" if len(x) == 0 else x)
    
    A_bug = base_data[base_data['customfields_title'] == ProjectConfig[projectId]['ProjectBugsLevel_Enumeration']['buglevel_A']]
    B_bug = base_data[base_data['customfields_title'] == ProjectConfig[projectId]['ProjectBugsLevel_Enumeration']['buglevel_B']]
    C_bug = base_data[base_data['customfields_title'] == ProjectConfig[projectId]['ProjectBugsLevel_Enumeration']['buglevel_C']]
    D_bug = base_data[base_data['customfields_title'] == ProjectConfig[projectId]['ProjectBugsLevel_Enumeration']['buglevel_D']]
    
    New_A = A_bug.groupby(['CreateWeek', 'bugType_name']).count()['tfsCreateTime']
    New_A = pd.DataFrame(New_A)
    New_A.reset_index(inplace=True)
    New_A.rename(columns={'tfsCreateTime' : "Create_A", 'CreateWeek' : 'week'}, inplace=True)
    
    New_B = B_bug.groupby(['CreateWeek', 'bugType_name']).count()['tfsCreateTime']
    New_B = pd.DataFrame(New_B)
    New_B.reset_index(inplace=True)
    New_B.rename(columns={'tfsCreateTime' : "Create_B", 'CreateWeek' : 'week'}, inplace=True)
    
    New_C = C_bug.groupby(['CreateWeek', 'bugType_name']).count()['tfsCreateTime']
    New_C = pd.DataFrame(New_C)
    New_C.reset_index(inplace=True)
    New_C.rename(columns={'tfsCreateTime' : "Create_C", 'CreateWeek' : 'week'}, inplace=True)
    
    New_D = D_bug.groupby(['CreateWeek', 'bugType_name']).count()['tfsCreateTime']
    New_D = pd.DataFrame(New_D)
    New_D.reset_index(inplace=True)
    New_D.rename(columns={'tfsCreateTime' : "Create_D", 'CreateWeek' : 'week'}, inplace=True)
    
    Close_A = A_bug.groupby(['CloseWeek', 'bugType_name']).count()['tfsCreateTime']
    Close_A = pd.DataFrame(Close_A)
    Close_A.reset_index(inplace=True)
    Close_A.rename(columns={'tfsCreateTime' : "Close_A", 'CloseWeek' : 'week'}, inplace=True)
    
    Close_B = B_bug.groupby(['CloseWeek', 'bugType_name']).count()['tfsCreateTime']
    Close_B = pd.DataFrame(Close_B)
    Close_B.reset_index(inplace=True)
    Close_B.rename(columns={'tfsCreateTime' : "Close_B", 'CloseWeek' : 'week'}, inplace=True)
    
    Close_C = C_bug.groupby(['CloseWeek', 'bugType_name']).count()['tfsCreateTime']
    Close_C = pd.DataFrame(Close_C)
    Close_C.reset_index(inplace=True)
    Close_C.rename(columns={'tfsCreateTime' : "Close_C", 'CloseWeek' : 'week'}, inplace=True)
    
    Close_D = D_bug.groupby(['CloseWeek', 'bugType_name']).count()['tfsCreateTime']
    Close_D = pd.DataFrame(Close_D)
    Close_D.reset_index(inplace=True)
    Close_D.rename(columns={'tfsCreateTime' : "Close_D", 'CloseWeek' : 'week'}, inplace=True)
    
    bugdata_ext = [New_A, New_B, New_C, New_D, Close_A, Close_B, Close_C, Close_D]
    del A_bug, B_bug, C_bug, D_bug
    del New_A, New_B, New_C, New_D, Close_A, Close_B, Close_C, Close_D
    
    suffixes_num = 0
    for i in bugdata_ext:
        df_template = pd.merge(df_template, i, how='left', on=['week', 'bugType_name'], suffixes=(f"_{suffixes_num}", f"_{suffixes_num+1}"))
        df_template.fillna(0, inplace=True)
        df_column1 = i.columns[-1]
        df_template[df_column1] = df_template[df_column1].astype('int64')
        suffixes_num += 1
            
    # 计算遗留bug
    df_template['Legacy_A'] = 0
    df_template['Legacy_B'] = 0
    df_template['Legacy_C'] = 0
    df_template['Legacy_D'] = 0
    
    bugState_map = {
        "buglevel_A" : "Legacy_A",
        "buglevel_B" : "Legacy_B",
        "buglevel_C" : "Legacy_C",
        "buglevel_D" : "Legacy_D",
    }
    
    bugState_map_ext = ProjectConfig[projectId]['ProjectBugsLevel_Enumeration']
    bugState_map_ext = {j:i for i, j in bugState_map_ext.items()}
    
    bugState_map_ext['一般'] = 'buglevel_C'    # 此行代码为了兼容大程序存在两个同样字段且同样缺陷等级id的奇葩数据！
    bugState_map_ext['严重'] = 'buglevel_B'
    
    ## 过滤掉创建周 == 关闭周 的数据
    LegacyBugs_df = base_data[base_data['CreateWeek'] != base_data['CloseWeek']]
    df_template.drop_duplicates(subset=['week', 'bugType_name'], keep='last', inplace=True)
    
    for row in df_template.itertuples():
        weekDate = getattr(row, "weekDate")
        df_template_bugTypeName = getattr(row, "bugType_name")
        rowIndex = getattr(row, 'Index')
        for LegacyBugs_row in LegacyBugs_df.itertuples():
            bugl = getattr(LegacyBugs_row, "customfields_title")
            CreateDay = int(getattr(LegacyBugs_row, "CreateDay"))
            CloseDay = int(getattr(LegacyBugs_row, "CloseDay"))
            LegacyBugs_df_bugTypeName = getattr(LegacyBugs_row, "bugType_name")
            if (weekDate >= CreateDay) and (weekDate < CloseDay) and (df_template_bugTypeName == LegacyBugs_df_bugTypeName):
                df_template.at[rowIndex, bugState_map[bugState_map_ext[bugl]]] += 1
                continue
    del LegacyBugs_df
                
    df_template['Week_Legacy_DI'] = (df_template['Legacy_A']*10 + df_template['Legacy_B']*3 + df_template['Legacy_C'] + df_template['Legacy_D']*0.3)
    df_template['Week_Create_DI'] = (df_template['Create_A']*10 + df_template['Create_B']*3 + df_template['Create_C'] + df_template['Create_D']*0.3)
    df_template['Week_Close_DI'] = (df_template['Close_A']*10 + df_template['Close_B']*3 + df_template['Close_C'] + df_template['Close_D']*0.3)
    df_template.drop(labels='weekDate', axis=1, inplace=True)
    df_template['projectId'] = projectId
    df_template.drop_duplicates(subset=['projectId', 'bugType_name', 'week'], keep='last', inplace=True)
    df_template.to_pickle(statisticsFile)
    return